#如果在某些情况下，我们也需要节省内存,就只能自己写。
# 我们自己写的这个能实现迭代器功能的东西就叫生成器

# 生成器Generator：
# 　　本质：迭代器(所以自带了__iter__方法和__next__方法，不需要我们去实现)
# 　　特点：惰性运算,开发者自定义

# 生成器函数
# 一个包含yield关键字的函数就是一个生成器函数。
# yield可以为我们从函数中返回值，但是yield又不同于return，
# return的执行意味着程序的结束，调用生成器函数不会得到返回的具体的值，
# 而是得到一个可迭代的对象。每一次获取这个可迭代对象的值，
# 就能推动函数的执行，获取新的返回值。直到函数执行结束。

# import time
# def genrator_fun1():
#     a = 1
#     print('现在定义了a变量')
#     yield a
#     b = 2
#     print('现在又定义了b变量')
#     yield b
#
# g1 = genrator_fun1()
# print('g1 : ',g1)       #打印g1可以发现g1就是一个生成器
# print('-'*20)   #我是华丽的分割线
# print(next(g1))
# time.sleep(1)   #sleep一秒看清执行过程
# print(next(g1))

# 生成器有什么好处呢？就是不会一下子在内存中生成太多数据

# def produce():
#     """生产衣服"""
#     for i in range(2000000):
#         yield "生产了第%s件衣服"%i
#
# product_g = produce()
# print("a"+product_g.__next__()) #要一件衣服
# print("b"+product_g.__next__()) #再要一件衣服
# print("c"+product_g.__next__()) #再要一件衣服
# num = 0
# for i in product_g:         #要一批衣服，比如5件
#     print(i)
#     num +=1
#     if num == 5:
#         break
import time

# def tail(filename):
#     f = open(filename)
#     f.seek(1,1) #用于移动文件读取指针到当前位置
#     while True:
#         line = f.readline()  # 读取文件中新的文本行
#         if not line:
#            break
#         yield line
#
# tail_g = tail("hosts.txt")
# for line in tail_g:
#     print(line)

# def generator():
#     print(123)
#     content = yield 1
#     print('=======',content)
#     print(456)
#     content1 = yield 2
#     print('=======',content1)
#     yield 'last data'
#
# g = generator()
# ret = g.__next__()
# print('***',ret)
# ret = g.send('hello')   #send的效果和next一样
# print('***',ret)
# ret1 = g.send('world')
# print('---',ret1)

#send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候，给上一yield的位置传递一个数据
#使用send的注意事项
# 第一次使用生成器的时候 是用next获取下一个值
# 最后一个yield不能接受外部的值

# def averager():
#     total = 0.0
#     count = 0
#     average = None
#     while True:
#         term = yield average
#         total += term
#         count += 1
#         average = total/count
#
#
# g_avg = averager()
# next(g_avg)
# print(g_avg.send(10))
# print(g_avg.send(30))
# print(g_avg.send(5))

# def init(func):#在调用被装饰生成器函数的时候首先用next激活生成器
#     def inner(*args,**kwargs):
#         g = func(*args,**kwargs)
#         next(g)
#         return g
#     return inner
#
# @init
# def averager():
#     total = 0.0
#     count = 0
#     average = None
#     while True:
#         term = yield average
#         total += term
#         count += 1
#         average = total/count
#
# g_avg = averager()
# print(g_avg.send(10))
# print(g_avg.send(30))
# print(g_avg.send(5))

# def gen1():
#     for c in 'AB':
#         yield c
#     for i in range(3):
#         yield i
# print(list(gen1()))

# def gen2():
#     yield from 'AB'
#     yield from range(3)
#
# print(list(gen2()))
# egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析
# laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式
# print(laomuji)
# print(next(laomuji))
# print(laomuji.__next__())
# print(next(laomuji))
from typing import Iterable
# def demo():
#     for i in range(4):
#         yield i
# g = demo()
# g1 = (i for i in g)
# g2 = (i for i in g1)
# g3 = (i for i in [1,2,3,4])
# print(isinstance(g,Iterable))
# print(isinstance(g1,Iterable))
# print(list(g1))
# print(list(g2))
# print(list(g3))

# list = [1,23,4,3,2]
# for i in list:
#     print(i)
# print(list)